package jinyilw.swing.visuals.text;

import jinyilw.common.math.MathTools;
import jinyilw.swing.ComponentTools;
import jinyilw.swing.FontTools;
import jinyilw.swing.graphics.RenderingConfig;
import jinyilw.swing.icon.LazyScaleIcon;
import jinyilw.swing.rlaf.theme.RThemeColor;

import javax.swing.Icon;
import javax.swing.JLabel;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.io.File;
import java.net.URL;

public class MultiLineLabel extends JLabel
{
	private static final long serialVersionUID = 8425186977448479454L;
	protected String[] texts;
	protected int[] textW;
	protected int[] textX, textY;
	private int hy, textH, textHgap;
	private int totalTextW, totalTextH;
	private boolean textCenter;
	private final RenderingConfig renderingConfig = new RenderingConfig();

	public MultiLineLabel()
	{
		initGUI();
	}

	public MultiLineLabel(Icon image, int horizontalAlignment)
	{
		super(image, horizontalAlignment);
		initGUI();
	}

	public MultiLineLabel(Icon image)
	{
		super(image);
		initGUI();
	}

	public MultiLineLabel(String[] texts)
	{
		this.texts = texts;
		initGUI();
	}

	private void initGUI()
	{
		setFont(FontTools.defaultFont);
	}

	@Override
	public void updateUI()
	{
		// setUI(new BasicLabelUI());
	}

	public void setParameter(String text, Font font, Color color)
	{
		super.setFont(font);
		setForeground(color);
		setText(text);
	}

	public void setTexts(String[] texts)
	{
		if (this.texts == texts)
			return;
		this.texts = texts;
		updateTSize(getFont());
		if (isShowing())
		{
			revalidate();
			repaint();
		}
	}

	public String[] getTexts()
	{
		return texts;
	}

	public void setTextCenter(boolean b)
	{
		if (textCenter != b)
		{
			textCenter = b;
			if (isShowing())
				repaint();
		}
	}

	@Override
	public void setFont(Font font)
	{
		if (font == null || font.equals(getFont()))
			return;
		updateTSize(font);
		super.setFont(font);
	}

	@Override
	public void setIcon(Icon icon)
	{
		super.setIcon(icon);
		if (icon != null)
		{
			imageW = icon.getIconWidth();
			imageH = icon.getIconHeight();
		} else
			imageW = imageH = 0;
	}

	@Override
	public Dimension getPreferredSize()
	{
		Insets insets = getInsets();
		//		if (totalTextW == 0)
		//			updateTSize(getFont());
		int width = totalTextW + imageW + gap + 6 + insets.left + insets.right;
		int height = Math.max(totalTextH, imageH) + insets.top + insets.bottom;
		return new Dimension(width, height);
	}

	//	public void setIcon(String name)
	//	{
	//		setIcon(LazyScaleIcon.getIcon(name));
	//	}

	public void setIcon(URL url)
	{
		setIcon(LazyScaleIcon.getIcon(url));
	}

	public void setIcon(File file)
	{
		setIcon(LazyScaleIcon.getIcon(file));
	}

	private int iX, iY, imageW, imageH, gap, rowHeight;

	private void updateTSize(Font font)
	{
		if (texts == null || font == null)
			return;
		FontMetrics fm = getFontMetrics(font);
		int length = texts.length;
		if (textW == null || textW.length < length)
			textW = new int[length];
		for (int i = 0; i < length; i++)
			textW[i] = texts[i] != null ? fm.stringWidth(texts[i]) : 0;
		hy = fm.getAscent();
		textH = fm.getHeight();
		rowHeight = textHgap > 0 ? textHgap : textH / 3;
		rowHeight += textH;
		totalTextH = rowHeight * length;
		totalTextW = MathTools.getMax(textW, length);
	}

	private void calculatePaints(int alignment)
	{
		int length = texts.length;
		if (textX == null || textX.length < length)
		{
			textX = new int[length];
			textY = new int[length];
		}
		Insets insets = getInsets();
		int width = getWidth() - insets.left - insets.right;
		int height = getHeight() - insets.top - insets.bottom;
		gap = 0;
		iX = insets.left;
		if (imageW > 0)
		{
			iY = (height - imageH) / 2 + insets.top;
			gap = getIconTextGap();
		}

		int ttY = (height - totalTextH) / 2 + hy + insets.top + 2;
		for (int i = 0; i < length; i++)
		{
			textY[i] = ttY;
			ttY += rowHeight;
		}
		int ttX;
		switch (alignment)
		{
			case CENTER:
				iX += (width - imageW - gap - totalTextW) / 2;
				ttX = iX + imageW + gap;
				for (int i = 0; i < length; i++)
					textX[i] = ttX;
				break;
			case RIGHT:
				iX += width - imageW - gap - totalTextW - 1;
				ttX = iX + imageW + gap;
				for (int i = 0; i < length; i++)
					textX[i] = ttX + totalTextW - textW[i];
				break;
			default:
				iX += 1;
				ttX = iX + imageW + gap;
				for (int i = 0; i < length; i++)
					textX[i] = ttX;
		}
		if (textCenter)
			for (int i = 0; i < length; i++)
				textX[i] = ttX + (totalTextW - textW[i]) / 2;
	}

	protected void drawText(Graphics2D g2d, Color color)
	{
		g2d.setColor(color);
		for (int i = 0; i < texts.length; i++)
			g2d.drawString(texts[i], textX[i], textY[i]);
	}

	@Override
	protected void paintComponent(Graphics g)
	{
		calculatePaints(getHorizontalAlignment());
		Graphics2D g2d = (Graphics2D) g;
		Composite composite = ComponentTools.applyEnableAlpha(g2d, isEnabled(),
				1f, 0.3f);
		Icon icon = getIcon();
		if (icon != null)
			icon.paintIcon(this, g2d, iX, iY);
		if (texts == null)
		{
			if (composite != null)
				g2d.setComposite(composite);
			return;
		}
		renderingConfig.setTextAADrawing(g2d);
		drawText(g2d, RThemeColor.colorSet.textColor);
		renderingConfig.resetTextAADrawing(g2d);
		if (composite != null)
			g2d.setComposite(composite);
	}
}
